//
// Created by LONG on 2020/11/8.
//

#include "l1Ul.h"
#include "../../../../o5gue/lcore/include/commDef.h"

void RAN_L1_UL_RecvDataFromUe(S_RanL1CellInst *pCellInst)
{
    uint32_t type;
    uint32_t size;
    uint32_t count;
    S_UeCommMsgHdr *pCommMsgHdr;

    count = 0;
    while (1)
    {
        pCommMsgHdr = VarRB_ReadRequest(pCellInst->pUeRanQue, &size);
        if (NULL == pCommMsgHdr)
        {
            usleep(1000);
            if (count++ > 10000)
            {
                assert(0);
            }
            continue;
        }

        type = pCommMsgHdr->type;

        VarRB_ReadConsume(pCellInst->pUeRanQue, pCommMsgHdr);

        if (UE_L1_API_MSG_BUTT == type)
        {
            break;
        }
    }
}

void RAN_L1_UL_CellProcess(S_RanL1CellInst *pCellInst)
{
    int32_t rc;
    S_OsSelectInd indMsg;
    S_RanL1ApiMsgSlotInd slotInd;

    RAN_L1_UL_RecvDataFromUe(pCellInst);

    if (APP_STATE_RUNNING == pCellInst->appState)
    {
        O5G_SfnSlot_Add(&pCellInst->sfn, &pCellInst->slot, pCellInst->slotNum, 1);

        slotInd.commMsgHdr.type = RAN_L1_API_MSG_SLOT_IND;
        slotInd.commMsgHdr.size = sizeof(slotInd);
        slotInd.nbIdx = pCellInst->nbIdx;
        slotInd.cellIdx = pCellInst->cellIdx;
        slotInd.sfn = pCellInst->sfn;
        slotInd.slot = pCellInst->slot;
        VRB_PUT(rc, pCellInst->pL1L2UpMsgQue, &slotInd, sizeof(slotInd));

        pCellInst->sendTtiIntCount++;

        indMsg.ind = RAN_L1_L2_IND_MSG_TTI_INT;
        OS_SelectSend(&pCellInst->ttiIntSelector, &indMsg);

//        CSP_LOG_INF(RAN_MD_L1_UL, "RAN_L1_CellUpProcess() send RAN_L1_API_MSG_SLOT_IND [%u, %u]\n", slotInd.sfn, slotInd.slot);
    }
}

void RAN_L1_UL_NodeBProcess(S_RanL1NbInst *pNbInst)
{
    uint32_t cellLoop;
    S_RanL1CellInst *pCellInst;

    for (cellLoop = 0; cellLoop < RAN_CELL_NUM_MAX; cellLoop++)
    {
        pCellInst = &pNbInst->cellInst[cellLoop];
        IF_CONTINUE(==, FALSE, pCellInst->inUse, NO_LOG_MESSAGE);
        RAN_L1_UL_CellProcess(pCellInst);
    }
}

void RAN_L1_UL_RanProcess()
{
    uint32_t nbLoop;
    S_RanL1NbInst *pNbInst;

    for (nbLoop = 0; nbLoop < RAN_NODEB_NUM_MAX; nbLoop++)
    {
        pNbInst = &gpRanL1Context->nbInst[nbLoop];
        IF_CONTINUE(==, FALSE, pNbInst->inUse, NO_LOG_MESSAGE);
        RAN_L1_UL_NodeBProcess(pNbInst);
    }
}

void RAN_L1_UL_Process(void)
{
    RAN_L1_UL_RanProcess();
}
